﻿#include <GL/glut.h>
#include <math.h>

void changeSize(int w, int h) {

        // Prevent a divide by zero, when window is too short
        // (you cant make a window with zero width).
        if(h == 0)
                h = 1;

        // compute window's aspect ratio 
        float ratio = w * 1.0 / h;

        // Set the projection matrix as current
        glMatrixMode(GL_PROJECTION);
        // Load Identity Matrix
        glLoadIdentity();
        
        // Set the viewport to be the entire window
    glViewport(0, 0, w, h);

        // Set perspective
        gluPerspective(45.0f ,ratio, 1.0f ,1000.0f);

        // return to the model view matrix mode
        glMatrixMode(GL_MODELVIEW);
}


float tx = 0;
float tz = 0;
float ay = 0; //angulo em graus

int face = GL_FRONT;
int modo = GL_FILL;

float a1 = 1, a2 = 0, a3 = 1;
float b1 = 1, b2 = 0, b3 = -1;
float c1 = -1, c2 = 0, c3 = -1;
float d1 = -1, d2 = 0, d3 = 1;
float e1 = 0, e2 = 2, e3 = 0;

void renderScene(void) {

        // clear buffers
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

        // set the camera
        glLoadIdentity();
        gluLookAt(3.0,6.0,6.0, 
                      0.0,0.0,0.0,
                          0.0f,1.0f,0.0f);

// p�r instru��es de desenho aqui

        glPolygonMode(face,modo); //para ver s� as linhas
        glDisable(GL_CULL_FACE); //para ver tb a parte de tr�s

        glBegin(GL_LINES);
                glColor3f(0,1,1);
                        glVertex3f(0,0,0);
                        glVertex3f(100,0,0);
                glColor3f(1,1,0);
                        glVertex3f(0,0,0);
                        glVertex3f(0,100,0);
                glColor3f(1,0,1);
                        glVertex3f(0,0,0);
                        glVertex3f(0,0,100);    
        glEnd();
        
        glTranslatef(tx, 0, tz);
        glRotatef(ay, 0, 1, 0);
        glBegin(GL_TRIANGLES);
                glColor3f(1,0,0);
                        glVertex3f(a1,a2,a3);
                        glVertex3f(b1,b2,b3);
                        glVertex3f(c1,c2,c3);
                        glVertex3f(c1,c2,c3);
                        glVertex3f(d1,d2,d3);
                        glVertex3f(a1,a2,a3);
                glColor3f(0,1,1);
                        glVertex3f(a1,a2,a3);
                        glVertex3f(b1,b2,b3);
                        glVertex3f(e1,e2,e3);
                glColor3f(1,0,0);
                        glVertex3f(b1,b2,b3);
                        glVertex3f(c1,c2,c3);
                        glVertex3f(e1,e2,e3);
                glColor3f(1,1,1);
                        glVertex3f(c1,c2,c3);
                        glVertex3f(d1,d2,d3);
                        glVertex3f(e1,e2,e3);
                glColor3f(1,1,0);
                        glVertex3f(d1,d2,d3);
                        glVertex3f(a1,a2,a3);
                        glVertex3f(e1,e2,e3);

        glEnd();

        // End of frame
        glutSwapBuffers();
}



// escrever fun��o de processamento do teclado
void teclado(unsigned char tecla, int x, int y){
        switch(tecla){
                case 'w': tx += 0.05; break;
                case 's': tx -= 0.05; break;
                case 'a': tz += 0.05; break;
                case 'd': tz -= 0.05; break;
                case 'n': ay += 0.5; break;
                case 'm': ay -= 0.5; break;
        }
        glutPostRedisplay();
}


// escrever fun��o de processamento do menu
void menu(int id_op){
        switch (id_op){
        case 1: modo = GL_FILL; break;
        case 2: modo = GL_LINE; break;
        case 3: modo = GL_POINT; break;
        case 5: face = GL_FRONT; break;
        case 6: face = GL_BACK; break;
        case 7: face = GL_FRONT_AND_BACK; break;
        default:
                break;
        }
        glutPostRedisplay();
}



int main(int argc, char **argv) {

// inicializa��o
        glutInit(&argc, argv);
        glutInitDisplayMode(GLUT_DEPTH|GLUT_DOUBLE|GLUT_RGBA);
        glutInitWindowPosition(100,100);
        glutInitWindowSize(800,800);
        glutCreateWindow("CG@DI-UM");
                

// registo de fun��es 
        glutDisplayFunc(renderScene);
        glutIdleFunc(nullptr);
        glutReshapeFunc(changeSize);

// p�r aqui registo da fun��es do teclado e rato
        glutKeyboardFunc(teclado);

// p�r aqui a cria��o do menu
        glutCreateMenu(menu);
        glutAddMenuEntry("GL_FILL",1);
        glutAddMenuEntry("GL_LINE",2);
        glutAddMenuEntry("GL_POINT",3);
        glutAddMenuEntry("-------",4);
        glutAddMenuEntry("GL_FRONT",5);
        glutAddMenuEntry("GL_BACK",6);
        glutAddMenuEntry("GL_FRONT_AND_BACK",7);
        glutAttachMenu(GLUT_RIGHT_BUTTON);

// alguns settings para OpenGL
        glEnable(GL_DEPTH_TEST);
        glEnable(GL_CULL_FACE);
        
// entrar no ciclo do GLUT 
        glutMainLoop();
        
        return 1;
}